/*
// jQuery multiSelect
//
// Version 1.0.2 beta
//
// Cory S.N. LaViska
// A Beautiful Site (http://abeautifulsite.net/)
// 10 May 2009
//
// Visit http://abeautifulsite.net/notebook.php?article=62 for more information
//
// Usage: $('#control_id').multiSelect( options, callback )
//
// Options:  selectAll          - whether or not to display the Select All option; true/false, default = true
//           selectAllText      - text to display for selecting/unselecting all options simultaneously
//           noneSelected       - text to display when there are no selected items in the list
//           oneOrMoreSelected  - text to display when there are one or more selected items in the list
//                                (note: you can use % as a placeholder for the number of items selected).
//                                Use * to show a comma separated list of all selected; default = '% selected'
//
// Dependencies:  jQuery 1.2.6 or higher (http://jquery.com/)
//
// Change Log:
//
//		1.0.1	- Updated to work with jQuery 1.2.6+ (no longer requires the dimensions plugin)
//				- Changed $(this).offset() to $(this).position(), per James' and Jono's suggestions
//
//		1.0.2	- Fixed issue where dropdown doesn't scroll up/down with keyboard shortcuts
//				- Changed '$' in setTimeout to use 'jQuery' to support jQuery.noConflict
//				- Renamed from jqueryMultiSelect.* to jquery.multiSelect.* per the standard recommended at
//				  http://docs.jquery.com/Plugins/Authoring (does not affect API methods)
//
// Licensing & Terms of Use
// 
// This plugin is dual-licensed under the GNU General Public License and the MIT License and
// is copyright 2008 A Beautiful Site, LLC. 
//	
*/
if(jQuery) (function(jQuery){
	
	var clazz = {
		hover:'multi-hover-flag',//ui-state-hover  multi-hover-flag
		labelHover:'ui-state-hover  multi-hover',
		active:'ui-state-hover',//
		focus:'ui-state-focus multi-focus',
		inputActive:'multi-input-active',
		inputFocus:'multi-input-focus',//input框的focus事件
		checked:'ui-state-active  multi-checked',
		selectAll:'selectAll'//'ui-state-default multi-selectall'
	}
	
	var isIE6 = function(){
		if (jQuery.browser.msie) {
		   return parseInt(jQuery.browser.version)<=6 ;
		}
		return false ;
	}
	var zIndex = 5 ;
	var isFirst = true ;

	jQuery.extend(jQuery.fn, {
		__multiSelect: function(o, callback) {
			if(o == undefined){return;}
			if(typeof o == 'string'){
				if(o == 'getValue'){
					return getValue.call(this) ;
				}else if(o == 'reload'){
					return reload.call(this) ;
				}
			}
		
			// Default options
			if( !o ) var o = {};
			if( o.selectAll == undefined ) o.selectAll = true;
			if( o.selectAllText == undefined ) o.selectAllText = "全 选";
			if( o.noneSelected == undefined ) o.noneSelected = '';
			
			if( o.oneOrMoreSelected == undefined ) o.oneOrMoreSelected = '% selected';
			
			// Initialize each multiSelect
			jQuery(this).each( function() {
				var select = jQuery(this);
				
				if( select.attr('defaultValue') ){
					var values = select.attr('defaultValue').split(',') ;
					$(values).each( function(){
						select.find("option[value="+this+"]").attr("selected","selected");  
					} ) ;
				}
				
				var width = jQuery(select).width();
				if(width<90)    
					width = 90; 
				var height = jQuery(select).height() * 2;
				if(height<100) height = 100 ;
				var html = '<span class="multiSelect-cont ui-widget"><input type="text" readonly="readonly" class="multiSelect combotree-text" value="" title="" style="cursor: default;width:' + (width-12) + ';" />';
				html+= '<span><span class="multiSelect-span ui-icon ui-icon-triangle-1-s"></span></span>' ;
				
				select.hide() ;
				var random = new Date().getTime() ;
				html += '<div class="multiSelectOptions ui-helper-reset ui-widget-content ui-corner-all" style="position: absolute;z-index:6; display: none;height:'  + height + ';width:' + width + ';">';
				if( o.selectAll ) html += '<label class="'+clazz.selectAll+'" for="'+random+'$$root'+'"><input type="checkbox" class="selectAll" id="'+random+'$$root'+'"/><span>' + o.selectAllText + '</span></label>';
				jQuery(select).find('OPTION').each( function() {
					if( jQuery(this).val() != '' ) {
						html += '<label for="'+random+jQuery(this).val()+'"><input type="checkbox" id="'+random+jQuery(this).val()+'"  value="' + jQuery(this).val() + '"';
						if( jQuery(this).attr('selected') ) html += ' checked="checked"';
						html += ' /><span title="'+jQuery(this).text()+'" >' + jQuery(this).html() + '</span></label>';
					}
				});
				
				html += '</div>';
				if(isIE6()){
					html+="<iframe style='border:none;background:none;display:none;position:absolute;height:"  + height + ";z-index:5;' src='about:blank'/>" ;
				}
				html += '</span>';
				//html+= '<div style="position: absolute; z-index: 100000;display:none;" class="multiSelect-span"></div>' ;
				jQuery(select).after(html);
				
				$(select).data("validate_target",$(select).next(".multiSelect-cont")) ;
				
				var _multiSelect = jQuery(select).next('span').find('.multiSelect') ;
				var _multiSelectOptions = jQuery(select).next('span').find('.multiSelectOptions') ;
				
				_multiSelectOptions.width( _multiSelect.parent().width() ) ;
				if(isIE6()){
					jQuery(select).next('span').find('iframe').width( _multiSelect.parent().width()) ;
				}
				
				var isOver = false ;
				$(document).click(function(e){
					if(!isOver && !clickBtn){
						optionsHide.call(_multiSelect);
					}
				}) ;
				
				_multiSelectOptions.mouseover(function(){
					isOver = true ;
				});
				
				// Events
				_multiSelect.mouseover( function() {
					jQuery(this).addClass(clazz.hover) ;//('hover');
				}).mouseout( function() {
					jQuery(this).removeClass(clazz.hover);//('hover');
				}).click( function() {
					// Show/hide on click
					if( jQuery(this).hasClass(clazz.inputActive) ) {
						optionsHide.call(jQuery(this));
					} else {
						optionsShow.call(jQuery(this));
					}
					return false;
				}).focus( function() {
					// So it can be styled with CSS
					jQuery(this).addClass(clazz.inputFocus);
				}).blur( function() {
					// So it can be styled with CSS
					jQuery(this).removeClass(clazz.inputFocus);
				});
				
				// Determine if Select All should be checked initially
				if( o.selectAll ) {
					var sa = true;
					_multiSelectOptions.find('INPUT:checkbox').not('.selectAll').each( function() {
						if( !jQuery(this).attr('checked') ) sa = false;
					});
					if( sa ) _multiSelectOptions.find('INPUT.selectAll').attr('checked', true).parent().addClass(clazz.checked);
				}
				
				// Handle Select All
				_multiSelectOptions.find('INPUT.selectAll').click( function() {
					if( jQuery(this).attr('checked') == true ) jQuery(this).parent().parent().find('INPUT:checkbox').attr('checked', true).parent().addClass(clazz.checked); else jQuery(this).parent().parent().find('INPUT:checkbox').attr('checked', false).parent().removeClass(clazz.checked);
				});
				
				// Handle checkboxes
				_multiSelectOptions.find('INPUT:checkbox').click( function() {
					var _opts = jQuery(this).parent().parent() ;
					updateSelected.call(_multiSelectOptions,o);
					_opts.find('LABEL').removeClass(clazz.checked).find('INPUT:checked').parent().addClass(clazz.checked);
					_opts.prev('span').find('.multiSelect').focus();
					if( !jQuery(this).attr('checked') ) 
						_opts.find('INPUT:checkbox.selectAll').attr('checked', false).parent().removeClass(clazz.checked);
					if( callback ) callback(jQuery(this));
				});
				
				// Initial display
				_multiSelectOptions.each( function() {
					updateSelected.call(_multiSelectOptions,o);
					jQuery(this).find('INPUT:checked').parent().addClass(clazz.checked);
				});
				
				// Handle hovers
				_multiSelectOptions.find('LABEL').mouseover( function() {
					jQuery(this).parent().find('LABEL').removeClass(clazz.labelHover);
					jQuery(this).addClass(clazz.labelHover);
				}).mouseout( function() {
					jQuery(this).parent().find('LABEL').removeClass(clazz.labelHover);
				});
				
				var clickBtn = false ;
				// Keyboard
				_multiSelect.keydown( function(e) {
					var _mso = jQuery(this).parent().find('.multiSelectOptions') ;
					// Is dropdown visible?
					if( _mso.is(':visible') ) {
						// Dropdown is visible
						// Tab
						if( e.keyCode == 9 ) {
							jQuery(this).addClass(clazz.focus).trigger('click'); // esc, left, right - hide
							jQuery(this).focus().next(':input').focus();
							return true;
						}
						
						// ESC, Left, Right
						if( e.keyCode == 27 || e.keyCode == 37 || e.keyCode == 39 ) {
							// Hide dropdown
							jQuery(this).addClass(clazz.focus).trigger('click');
						}
						// Down
						if( e.keyCode == 40 ) {
							if( !_mso.find('LABEL').hasClass(clazz.labelHover) ) {
								// Default to first item
								_mso.find('LABEL:first').addClass(clazz.labelHover);
							} else {
								// Move down, cycle to top if on bottom
								_mso.find('LABEL.'+clazz.labelHover).removeClass(clazz.labelHover).next('LABEL').addClass(clazz.labelHover);
								if( !_mso.find('LABEL').hasClass(clazz.labelHover) ) {
									_mso.find('LABEL:first').addClass(clazz.labelHover);
								}
							}
							
							// Adjust the viewport if necessary
							adjustViewport(jQuery(this) );
							
							return false;
						}
						// Up
						if( e.keyCode == 38 ) {
							if( !_mso.find('LABEL').hasClass(clazz.labelHover) ) {
								// Default to first item
								_mso.find('LABEL:first').addClass(clazz.labelHover);
							} else {
								// Move up, cycle to bottom if on top
								_mso.find('LABEL.'+clazz.labelHover).removeClass(clazz.labelHover).prev('LABEL').addClass(clazz.labelHover);
								if( !_mso.find('LABEL').hasClass(clazz.labelHover) ) {
									_mso.find('LABEL:last').addClass(clazz.labelHover);
								}
							}
							
							// Adjust the viewport if necessary
							adjustViewport(jQuery(this) );
							
							return false;
						}
						// Enter, Space
						if( e.keyCode == 13 || e.keyCode == 32 ) {
							// Select All
							if( _mso.find('LABEL.'+clazz.labelHover+' INPUT:checkbox').hasClass('selectAll') ) {
								if(_mso.find('LABEL.'+clazz.labelHover+' INPUT:checkbox').attr('checked') ) {
									// Uncheck all
									_mso.find('INPUT:checkbox').attr('checked', false).parent().removeClass(clazz.checked);
								} else {
									// Check all
									_mso.find('INPUT:checkbox').attr('checked', true).parent().addClass(clazz.checked);
								}
								updateSelected.call(_mso,o);
								if( callback ) callback(jQuery(this));
								return false;
							}
							// Other checkboxes
							if( _mso.find('LABEL.'+clazz.labelHover+' INPUT:checkbox').attr('checked') ) {
								// Uncheck
								_mso.find('LABEL.'+clazz.labelHover+' INPUT:checkbox').attr('checked', false);
								updateSelected.call(_mso,o);
								_mso.find('LABEL').removeClass(clazz.checked).find('INPUT:checked').parent().addClass(clazz.checked);
								// Select all status can't be checked at this point
								_mso.find('INPUT:checkbox.selectAll').attr('checked', false).parent().removeClass(clazz.checkeds);
								if( callback ) callback(jQuery(this));
							} else {
								// Check
								_mso.find('LABEL.'+clazz.labelHover+' INPUT:checkbox').attr('checked', true);
								updateSelected.call(_mso,o);
								_mso.find('LABEL').removeClass(clazz.checked).find('INPUT:checked').parent().addClass(clazz.checked);
								if( callback ) callback(jQuery(this));
							}
						}
						return false;
					} else {
						// Dropdown is not visible
						if( e.keyCode == 38 || e.keyCode == 40 || e.keyCode == 13 || e.keyCode == 32 ) { // down, enter, space - show
							// Show dropdown
							jQuery(this).removeClass(clazz.focus).trigger('click');
							_mso.find('LABEL:first').addClass(clazz.labelHover);
							return false;
						}
						//  Tab key
						if( e.keyCode == 9 ) {
							// Shift focus to next INPUT element on page
							jQuery(this).focus().next(':input').focus();
							return true;
						}
					}
					// Prevent enter key from submitting form
					if( e.keyCode == 13 ) return false;
				});
				
				//jQuery(select).hide();
				
				
				var offset = _multiSelect.position();
				_multiSelect.next('span').find('.multiSelect-span')
					.click( function(){
						jQuery(this).parent().prev('.multiSelect').click();
						clickBtn = true ;
					} ) ;
				// Eliminate the original form element
				//jQuery(select).remove();
					
					
					function updateSelected(o) {
						var _multiSelectOptions = jQuery(this) ;
						var _multiSelect = jQuery(this).parent('span').find('INPUT.multiSelect') ;
						var i = 0, s = '';
						_multiSelectOptions.find('INPUT:checkbox:checked').not('.selectAll').each( function() {
							i++;
						})
						
						if( i == 0 ) {
							select.find("option").attr("selected",false); 
							_multiSelect.val( o.noneSelected );
						} else {
							if( o.oneOrMoreSelected == '*' ) {
								var display = [];
								
								select.find("option").attr("selected",false);
								
								_multiSelectOptions.find('INPUT:checkbox:checked').each( function() {
									if( $(this).parent().text() != o.selectAllText ) 
										display.push(jQuery.trim( $(this).parent().text() )) ;
									select.find("option[value="+this.value+"]").attr("selected","selected");  
								});
								_multiSelect.val( display.join(",") );
								
							} else {
								_multiSelect.val( o.oneOrMoreSelected.replace('%', i) );
							}
							
						}
						_multiSelect.attr("title",_multiSelect.val());
						if(!isFirst && $.validation){
							$.validation.loadValidation(select);
							if(select.change)select.change();
						}
						isFirst = false ;
					}
					
					// Hide the dropdown
					function optionsHide() {
						isOver = false ;
						clickBtn = false ;
						jQuery(this).removeClass(clazz.inputActive).parent().find('.multiSelectOptions').hide()
						.css({position:'','z-index':0}).parent().css({position:'','z-index':0});
						jQuery(this).removeClass(clazz.inputActive).parent().find('iframe').hide();
						
					} ;
					
					// Show the dropdown
					function optionsShow() {
						
						var _multiSelectOptions = jQuery(this).parent().find('.multiSelectOptions') ;
						// Hide any open option boxes
						optionsHide.call(jQuery('.multiSelect'));
						_multiSelectOptions.css({position:'absolute','z-index':10}).parent().css({position:'relative','z-index':1}) ;
						_multiSelectOptions.find('LABEL').removeClass(clazz.labelHover);
						jQuery(this).addClass(clazz.inputActive).parent().find('.multiSelectOptions').show();
						
						// Position it
						var offset = jQuery(this).position();
						
						_multiSelectOptions
							.css({ top:  (offset.top + jQuery(this).parent().outerHeight() - 1)+ 'px' })
							.css({ left: 0 }) ;//(offset.left-1) + 'px'
						
						if(isIE6()){
							_multiSelectOptions.next("iframe")
							.css({ top:  (offset.top + jQuery(this).parent().outerHeight() - 1)+ 'px' })
							.css({ left: 0 }).show();
						}	
						
						// Disappear on hover out
						multiSelectCurrent = jQuery(this);
						var timer = '';
						_multiSelectOptions.hover( function() {
							clearTimeout(timer);
						}, function() {
							//'optionsHide.call(jQuery(multiSelectCurrent)); jQuery(multiSelectCurrent).unbind("hover");'
							timer = setTimeout(function(){
								optionsHide.call(jQuery(multiSelectCurrent)); 
								jQuery(multiSelectCurrent).unbind("hover");
								multiSelectCurrent.next("iframe").hide();
							}, 250);
						});
						
						/*$(document).unbind('.multiSelectOptions').bind('click not(.multiSelectOptions input)', function(){
							jQuery(multiSelectCurrent).multiSelectOptionsHide()
							return false;
						});*/
						
					};
					
					// Ensures that the selected item is always in the visible portion of the dropdown (for keyboard controls)
					function adjustViewport(el) {
						// Calculate positions of elements
						var i = 0;
						var selectionTop = 0, selectionHeight = 0;
						jQuery(el).parent().find('.multiSelectOptions').find('LABEL').each( function() {
							if( jQuery(this).hasClass(clazz.hover) ) { selectionTop = i; selectionHeight = jQuery(this).outerHeight(); return; }
							i += jQuery(this).outerHeight();
						});
						var divScroll = jQuery(el).parent().find('.multiSelectOptions').scrollTop();
						var divHeight = jQuery(el).parent().find('.multiSelectOptions').height();
						// Adjust the dropdown scroll position
						jQuery(el).parent().find('.multiSelectOptions').scrollTop(selectionTop - ((divHeight / 2) - (selectionHeight / 2)));
					}
			});
			
			function  getValue(){
			 	var retObj = [] ;
				$(this).find('option[selected]').each(function(){
					var val = this.value ;
					var text = $.trim($(this).text()) ;
					retObj.push( {value:val,text:text} ) ;
				}) ;
				return retObj;
			};
			
			function reload(){
				$(this).next('.multiSelect-cont').remove() ;
			}
		}
	}); 
	
	$.multiSelectInit = function(jqueryObj,json4Options){
		var omultiSelect = new multiSelectWidget();
		omultiSelect.init(jqueryObj,json4Options);
		// jqueryObj.__multiSelect(json4Options);
	};
	
	$.fn.multiSelect = function(json_obj){
		var msw = $.data( $(this)[0] ,"msw") ;
		if(msw){
			return msw;
		}
		
		var omultiSelect = new multiSelectWidget();
		omultiSelect.init($(this),json_obj);
		
		$.data( $(this)[0] ,"msw" , omultiSelect );
		return omultiSelect;
	};
	
	multiSelectWidget = function(){
		var self = this ;
		this.$ = null;
		
		this.init = function(jquery_obj,json_obj){
			this.$ = jquery_obj;
			json_obj = json_obj||{} ;
			this.options = json_obj ;
			if(json_obj.CommandName || json_obj.url ){
				json_obj.params = json_obj.params||{} ;
				json_obj.params.format = 'false' ;
				$.dataservice( json_obj.CommandName , json_obj.params , function(data){//ID , TEXT
					jquery_obj.empty();
					$(data).each(function(){
						var id 		= this.ID||this.id ;
						var text 	= this.TEXT||this.Text ; 
						if( !id || !text ) return ;
						jquery_obj.append("<option value='"+id+"'>"+text+"</option>") ;
					}) ;
					self.render(json_obj) ;
				}  , {url:json_obj.url} ) ;
			}else{
				this.render(json_obj) ;
			}
		};
		
		this.render = function(json_obj){
			if(json_obj != undefined){
				this.$.__multiSelect(json_obj);
			}
		}
		
		this.getValue = function(){
			return this.$.__multiSelect('getValue');
		};
		
		this.reload = function(options){
			this.$.__multiSelect('reload');
			this.options = $.extend(this.options,options||{}) ;
			this.init(this.$,this.options) ;
		}
	};
	
})(jQuery);